package cn.kmia.hrm.realm;

import cn.kmia.hrm.pojo.system.Permission;
import cn.kmia.hrm.pojo.system.Role;
import cn.kmia.hrm.pojo.system.User;
import cn.kmia.hrm.service.system.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.nutz.dao.Dao;
import org.nutz.integration.shiro.SimpleShiroToken;
import org.nutz.mvc.Mvcs;

/**
 * @program: hrm
 * @description: shiro自定义验证
 * @author: 4K
 * @create: 2018-04-25 13:27
 **/
public class SimpleAuthorizingRealm extends AuthorizingRealm {

    /**
     * 用户认证
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        SimpleShiroToken upToken = (SimpleShiroToken) token;
        if (upToken == null)
            return null;
        Dao dao = Mvcs.ctx().getDefaultIoc().get(Dao.class, "dao");
        User user = dao.fetch(User.class, ((Integer)upToken.getPrincipal()).longValue());
        if (user == null)
            return null;
        if (user.isLocked())
            throw new LockedAccountException("用户[" + user.getUser_idcard() + "] 被锁定.");
        return new SimpleAccount(user.getId(), user.getUser_pwd(), getName());
    }

    /**
     * 权限认证
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        if (principals == null) {
            throw new AuthorizationException("用户信息获取失败");
        }
        int userId = (Integer) principals.getPrimaryPrincipal();
        Dao dao = Mvcs.ctx().getDefaultIoc().get(Dao.class, "dao");
        User user = dao.fetch(User.class, userId);
        if (user == null)
            return null;
        if (user.isLocked())
            throw new LockedAccountException("用户[" + user.getUser_idcard() + "] 被锁定.");

        SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo();
        UserService userService = Mvcs.ctx().getDefaultIoc().get(UserService.class);
        user = userService.getRolesAndPers(user);
        if (user.getRoles() != null) {
            for (Role role : user.getRoles()) {
                auth.addRole(role.getName());
                if (role.getPermissions() != null) {
                    for (Permission p : role.getPermissions()) {
                        auth.addStringPermission(p.getName());
                    }
                }
            }
        }
        return auth;
    }

    /**
     * 覆盖父类的验证,直接pass
     */
    protected void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException {
    }

    public SimpleAuthorizingRealm() {
        this(null, null);
    }

    public SimpleAuthorizingRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
        super(cacheManager, matcher);
        setAuthenticationTokenClass(SimpleShiroToken.class);
    }

    public SimpleAuthorizingRealm(CacheManager cacheManager) {
        this(cacheManager, null);
    }

    public SimpleAuthorizingRealm(CredentialsMatcher matcher) {
        this(null, matcher);
    }
}
